package com.example.questionnaire.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.example.questionnaire.common.ResponseCode;
import com.example.questionnaire.common.ServerResponse;
import com.example.questionnaire.dao.*;
import com.example.questionnaire.exception.RException;
import com.example.questionnaire.pojo.DO.*;
import com.example.questionnaire.service.LoginPageService;
import com.example.questionnaire.util.CommonUtil;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.util.*;

import static cn.hutool.core.text.StrSpliter.split;

@Service
public class LoginPageServiceImpl implements LoginPageService {


    @Autowired
    private UserMapper userMapper;

    @Autowired
    private AppidAndSecretMapper appidAndSecretMapper;

    @Override
    public User wxLogin(String code) throws IOException {

        System.out.println("code: "+code);
        QueryWrapper<AppidAndSecret> wrapper1 = new QueryWrapper<>();
        wrapper1.select("appid","secret");
        AppidAndSecret appidAndSecret = appidAndSecretMapper.selectOne(wrapper1);


        String appid = appidAndSecret.getAppid();
        String secret = appidAndSecret.getSecret();
        String url = String.format("https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code", appid, secret, code);

        HttpClient client = new DefaultHttpClient();
        HttpGet httpGet = new HttpGet(url);
        HttpResponse response = client.execute(httpGet);

        String result = EntityUtils.toString(response.getEntity(), "UTF-8");


//        System.out.println("result: "+result);
        JSONObject jsonObject = JSON.parseObject(result);
        String openId = jsonObject.getString("openid");
        String sessionKey = jsonObject.getString("session_key");

//        System.out.println("openId: "+openId);
        if(openId == null){
            throw new RuntimeException("登录失败");
        }


        long expirationTime = 86400000L; // 过期时间设定为一天
        String token = Jwts.builder()
                     .setSubject(openId) // 设置 Token 主题
                     .setIssuedAt(new Date()) // 设置 Token 签发时间
                     .setExpiration(new Date(System.currentTimeMillis() + expirationTime)) // 设置 Token 过期时间
                     .signWith(SignatureAlgorithm.HS256, secret) // 使用指定的加密算法和密钥生成签名
                     .compact(); // 生成最终的 Token 字符串

        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("open_id",openId);
        User user2 = userMapper.selectOne(wrapper);
        if(user2 != null){
            UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
            updateWrapper.eq("open_id", openId);
            updateWrapper.set("session_key", sessionKey);
            updateWrapper.set("token", token);
            int i = userMapper.update(null, updateWrapper);
            if (i < 1){
                throw new RuntimeException("更新秘钥和token失败");
            }
        }else {
            User user = new User();
            user.setOpenId(openId);
            user.setToken(token);
            user.setSessionKey(sessionKey);

            int i = userMapper.insert(user);
            if (i < 1) {
                throw new RuntimeException("插入失败");
            }
        }
        User user1 = new User();
        user1.setOpenId(openId);
        user1.setToken(token);

       return user1;

    }

    @Override
    public ServerResponse phoneEnroll(String phone, String password) {
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("phone", phone);
        int i = userMapper.selectCount(wrapper);
        if (i > 0){
            return ServerResponse.createByUserExistError("注册失败，已有用户");
        }

        User user = new User();
        user.setPhone(phone);
        user.setPassword(password);
        userMapper.insert(user);

        return ServerResponse.createBySuccess("注册成功");
    }

    @Override
    public ServerResponse phoneLogin(String phone, String password) {

        QueryWrapper<AppidAndSecret> wrapper1 = new QueryWrapper<>();
        wrapper1.select("secret");
        AppidAndSecret appidAndSecret = appidAndSecretMapper.selectOne(wrapper1);
        String secret = appidAndSecret.getSecret();
        long expirationTime = 86400000L; // 过期时间设定为一天
        String token = Jwts.builder()
                .setSubject(phone) // 设置 Token 主题
                .setIssuedAt(new Date()) // 设置 Token 签发时间
                .setExpiration(new Date(System.currentTimeMillis() + expirationTime)) // 设置 Token 过期时间
                .signWith(SignatureAlgorithm.HS256, secret) // 使用指定的加密算法和密钥生成签名
                .compact(); // 生成最终的 Token 字符串

        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("phone", phone);
        User user = userMapper.selectOne(wrapper);
        if (user != null) {
            if (password.equals(user.getPassword())) {
                //密码正确，更新用户的登陆凭证（token）
                UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
                updateWrapper.eq("phone", phone);
                updateWrapper.set("token", token);
                int i = userMapper.update(null, updateWrapper);

                if (i < 1) {
                    throw new RuntimeException("更新token失败");
                }

                return ServerResponse.createBySuccess2("登录成功",token);
            } else {
                //密码错误，登陆失败
                return ServerResponse.createByError("登录失败，密码错误");

            }
        } else {
            // 用户不存在，登录失败
            return ServerResponse.createByError("登录失败，用户不存在");
        }

    }

}
